﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HS_Model.Character;
using System.IO;

/**********************************************/
static class constantes{
    public const double ZONA_SOLDADOS = 0.6;
    public const int NFILAS = 15;
    public const int NCOLUMNAS = 60;
    public const int MONTOI = 500;
}
/**********************************************/

namespace HS_Model.World {
    public class Game {
        /*Atributos*/
        private int numSoldados;
        private int numCriaturas;
        private Map mapa; /*viene inicializado*/
        private int dineroAcumulado;
        private List<Soldier> listSoldados = new List<Soldier>();
        private List<Monster> listMonstruos=new List<Monster>();

        /*Constructores*/
        public Game() {
            this.numSoldados = 0; /*habra que cambiar este valor ecuando corre juego, en program*/
            this.numCriaturas = 0; /*habra que cambiar este valor ecuando corre juego, en program*/
            /*this.mapa =  seria algo ilogico ya viene instanciado*/
            this.dineroAcumulado = constantes.MONTOI; // valor opcional, luego modificar
            /*habra que ir metiendi los soldados y criaturas cuando corre juego, ademas de actualizar numSoldados y numCriaturas*/
            this.mapa = new Map(constantes.NCOLUMNAS,constantes.NFILAS, "Mundo1",constantes.MONTOI, "Lleno de paisajes y muchos peligros");
        }

        /*Metodos Sets y Gets*/
        public void setNumSoldados(int numSoldados) {
            this.numSoldados = numSoldados;
        }
        public int getNumSoldados() {
            return numSoldados;
        }

        public void setNumCriaturas(int numCriaturas) {
            this.numCriaturas = numCriaturas;
        }
        public int getNumCriaturas() {
            return numCriaturas;
        }
        
        public void setMapa(Map mapa) {
            this.mapa = mapa;
        }
        public Map getMapa() {
            return mapa;
        }
        
        public void setDineroAcumulado(int dineroAcumulado) {
            this.dineroAcumulado = dineroAcumulado;
        }
        public int getDineroAcumulado() {
            return dineroAcumulado;
        }        
        
        public void setListSoldados(List<Soldier> listSoldados) {
            this.listSoldados = listSoldados;
        }
        public List<Soldier> getListSoldados() {
            return listSoldados;
        }

        /*public List<Monstruo> ListMonstruos
        {
            get { return listMonstruos; }
            set { listMonstruos = value; }
        }*/

        /*Metodos Otros*/
        public char mostrarMenuJuego() {
            System.Console.WriteLine("\nMENU PRINCIPAL");
            System.Console.WriteLine("1) Comprar Soldados");
            System.Console.WriteLine("2) Jugar Ahora");
            System.Console.WriteLine("3) Reiniciar Ahora");
            System.Console.WriteLine("4) Salir Ahora");
            System.Console.Write("Opcion: ");
            ConsoleKeyInfo opcion = Console.ReadKey();
            return opcion.KeyChar;
        }
        /***************************************************************/
        public char mostrarMenuSoldado() {
            System.Console.WriteLine("\n\nMENU COMPRAR SOLDADOS     DINERO DISPONIBLE = "+ dineroAcumulado);
            System.Console.WriteLine("Pistolero   : P");
            System.Console.WriteLine("Lanzallamas : F");
            System.Console.WriteLine("Bazukero    : B");            
            System.Console.Write("Opcion:     ");

            /*debemos verificar que se ingrese un tipo de soldado correcto*/
            char x;
            string posX = Console.ReadLine(); //aca vemos que tipo de soldado se quiere comprar, debemos analizar el jugador tiene sufciciente dinero
            while (true) {
                if (char.TryParse(posX, out x)) {
                    if ((x != 'P') && (x != 'F') && (x != 'B')) {
                        Console.WriteLine("Coloque un valor correcto, los caracteres validos son : (P:Pistolero) (F:Lanzallamas) (B:Bazukero)");
                        Console.WriteLine("Coloque de nuevo el tipo de Soldado");
                        Console.Write("Tipo de Soldado : ");
                        posX = Console.ReadLine();
                        continue;
                    }
                    break;
                }
                else {
                    /*caso se ingresa un valor numerico*/
                    Console.WriteLine("Coloque un valor tipo caracter");
                    Console.WriteLine("Coloque de nuevo el tipo de Soldado");
                    Console.Write("Tipo de Soldado : ");
                    posX = Console.ReadLine();
                    continue;
                }
            }
            x = System.Convert.ToChar(posX);
            return x;
        }
        /***************************************************************/
        public void cargarSoldados() {
            char opcion;
            opcion =mostrarMenuSoldado(); // debera mostrar el menu para agregar que tipo de soldado se agregara            
            
            Console.WriteLine("\n");
            Console.WriteLine("=====================================");
            Console.WriteLine("|Dónde desea colocar al soldado?    |");
            Console.WriteLine("=====================================");

            int x, y;

            //Capturando el Parámetro X:
            Console.Write("Posición Horizontal: ");
            string posX = Console.ReadLine();
            while (true) {
                if (int.TryParse(posX, out x)) {
                    if (x > (int)(mapa.getAncho()*constantes.ZONA_SOLDADOS)) {
                        /*cuando se pasa del limite del tablero en sentido horizontal*/
                        Console.WriteLine("Coloque un valor correcto por restriccion de area reservada para soldados, debe ser menor a " + mapa.getAncho() * constantes.ZONA_SOLDADOS);
                        Console.WriteLine("Coloque de nuevo la Posición Horizontal");
                        Console.Write("Posición Horizontal: ");
                        posX = Console.ReadLine();
                        continue;
                    }                    
                    break;
                }
                else {
                    Console.WriteLine("Coloque un valor numérico");
                    Console.WriteLine("Coloque de nuevo la posición Horizontal");
                    Console.Write("Posición Horizontal: ");
                    posX = Console.ReadLine();
                    continue;
                }
            }
            x = System.Convert.ToInt32(posX);

            //Capturando el parámetro Y:
            Console.Write("Posición Vertical: ");
            string posY = Console.ReadLine();
            while (true) {
                if (int.TryParse(posY, out y)) {
                    if (y >= mapa.getAlto()) {
                        /*cuando se pasa del limite del tablero en sentido vertical*/
                        Console.WriteLine("Coloque un valor correcto, debe ser menor a " + mapa.getAlto());
                        Console.WriteLine("Coloque de nuevo la Posición Vertical");
                        Console.Write("Posición Vertical: ");
                        posY = Console.ReadLine();
                        continue;
                    }
                    break;
                }
                else {
                    Console.WriteLine("Coloque un valor numérico");
                    Console.WriteLine("Coloque de nuevo la Posición Vertical");
                    Console.Write("Posición Vertical: ");
                    posY = Console.ReadLine();
                    continue;
                }
            }
            y = System.Convert.ToInt32(posY);

            /*Verificando que una celda esté disponible para instanciarla*/
            if (((getMapa().getTablero())[y][x]).getTipoElemento() == ' ') {
                
                //ME PARECE QUE ESTÁ COLOCANDO LOS PARÁMETROS AL REVÉS, NO SERÍA PRIMERO X Y LUEGO EL Y?
                //Soldier sold = new Soldier(opcion, x, y);
                Soldier sold = new Soldier(opcion, y, x);
                if (this.getDineroAcumulado() < sold.getExistenceCost()) {
                    /*no hay suficiente costo para comprar*/
                    Console.WriteLine("Insuficiente dinero, dinero Disponible : " + dineroAcumulado + " Costo Soldado : " + sold.getExistenceCost());
                    Console.WriteLine("Lo sentimos no se realizo la compra del elemento requerido");
                }
                else {
                    //Instanciamos y luego lo agregamos en la lista de soldados:
                    listSoldados.Add(sold); //agregamos a la lista de soldados
                    dineroAcumulado = dineroAcumulado - sold.getExistenceCost(); //reducimos su dinero para la siguiente compra
                    /*Modificamos el tablero para que se pueda visualizar*/
                    ((getMapa().getTablero())[y][x]).setTipoElemento(opcion);
                    ((getMapa().getTablero())[y][x]).setX(y);
                    ((getMapa().getTablero())[y][x]).setY(x);
                }
            }
            else {
                Console.WriteLine("Coloque un valor correcto la proxima vez, ya existe un elemnto en la posicion [fila,columna] " + "(" + y + "," + x + ")");
                Console.WriteLine("Lo sentimos no se almaceno el elemento requerido");
            }   
        }/*fin metodo*/

        /***************************************************************/
        public void imprimirListaSoldados(){

            Console.WriteLine("\n\nLISTA DE SOLDADOS CREADOS (fila, columna, tipo)  CANTIDAD SOLDADOS = " + listSoldados.Count());
            Console.WriteLine("Por favor, especifique el tipo de soldado que quiere mover");
            ConsoleKeyInfo opcMov = Console.ReadKey();

            if ((opcMov.KeyChar == 'P') || (opcMov.KeyChar == 'p'))
            {
                for (int i = 0; i < listSoldados.Count(); i++)
                    if (listSoldados[i].getType() == 'P')
                        Console.WriteLine("(" + listSoldados[i].getY() + ", " + listSoldados[i].getX() + ", " + listSoldados[i].getType() + ")");
            }

            if ((opcMov.KeyChar == 'f') || (opcMov.KeyChar == 'F'))
            {
                for (int i = 0; i < listSoldados.Count(); i++)
                    if (listSoldados[i].getType() == 'F')
                        Console.WriteLine("(" + listSoldados[i].getY() + ", " + listSoldados[i].getX() + ", " + listSoldados[i].getType() + ")");
            }

            if ((opcMov.KeyChar == 'b') || (opcMov.KeyChar == 'B'))
            {
                for (int i = 0; i < listSoldados.Count(); i++)
                    if (listSoldados[i].getType() == 'B')
                        Console.WriteLine("(" + listSoldados[i].getY() + ", " + listSoldados[i].getX() + ", " + listSoldados[i].getType() + ")");
            }


         }
        /***************************************************************/
        
        
        
        
        
        
        public void cargarMonstruos() {
            Random r = new Random(DateTime.Now.Millisecond);
            int numMons = r.Next(3, 80);
                        
            for (int i = 1; i <= numMons; i++) {
                int posX = r.Next((int)(constantes.ZONA_SOLDADOS*constantes.NCOLUMNAS), constantes.NCOLUMNAS);
                int posY = r.Next(0, (constantes.NFILAS)-1);
                int tipoEnt = r.Next(1, 10);
                char tipoChar;
                if ((tipoEnt%2)==0) tipoChar='S';
                else tipoChar='D';
                               
                Monster mons = new Monster(tipoChar,posX,posY);

                /*verificamos que no haya un monstruo ya en la celda*/
                if (((getMapa().getTablero())[posY][posX]).getTipoElemento() == ' ') {
                    listMonstruos.Add(mons);
                    ((getMapa().getTablero())[posY][posX]).setTipoElemento(tipoChar);
                }
                else {
                    Console.WriteLine("No se agrego monstruo "+i+" debido a que ya hay uno en la posicion");
                    i--;
                }
            }
        }
        /***************************************************************/
        public void imprimirListaMonstruos() {
            Console.WriteLine("\nLISTA DE MONSTRUOS CREADOS  (fila,columna,tipo)  CANTIDAD MONSTRUOS = " + listMonstruos.Count());
            for (int i = 0; i < listMonstruos.Count(); i++)
                Console.WriteLine("(" + listMonstruos[i].getY() + "," + listMonstruos[i].getX() + "," + listMonstruos[i].getTypeMonster() + ")");
        }

    }
}
